﻿using AntdUI.In;
using AntdUI;
using Google.Protobuf.WellKnownTypes;
using PosClient.Controls.ViewModel;
using PosClient.Delegates;
using PosClient.Model;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using PosClient.Interfaces;

namespace PosClient.Controls
{
    public partial class PluRowPro : UserControl, IViewFor<PluRowViewModel>, IRow
    {
        object IViewFor.ViewModel
        {
            get => ViewModel;
            set => ViewModel = (PluRowViewModel)value;
        }
        public PluRowViewModel ViewModel { get; set; }

        public UserControl control { get => this; }

        public event RowClickEventHandler RowClick;

        public event RowValueEventHandler RowValue;

        public event RowDisposeEventHandler RowDispose;

        public PluRowPro()
        {
            InitializeComponent();

            InitBinding();

            InitEvent();
        }

        private void InitBinding()
        {
            ViewModel = new PluRowViewModel();
            this.WhenActivated(d =>
            {
                this.OneWayBind(ViewModel,
                    vm => vm.Plu.PluSvg,
                    v => v.label_name.PrefixSvg
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Plu.PluName,
                    v => v.label_name.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Index,
                    v => v.label_index.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Plu.PluCode,
                    v => v.label_index.Suffix
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Plu.Amount,
                    v => v.label_amount.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Plu.Amount,
                    v => v.label_amount.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Plu.Price,
                    v => v.label_price.Text
                    ).DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.TagColor,
                    v => v.panel_tag.Back
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Plu.Count,
                    v => v.label_count.Text
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Plu,
                    v => v.label_originprice.Text,
                    ConvertToPriceUnit)
                    .DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsChecked,
                    v => v.stackPanel_base.BackColor,
                    BoolToBorderStyle,
                    BorderStyleToBool
                    ).DisposeWith(d);

                this.Bind(ViewModel,
                    vm => vm.IsChecked,
                    v => v.label_close.BackColor,
                    BoolToBorderStyle,
                    BorderStyleToBool
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.IsChecked,
                    v => v.label_close.Visible
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.IsVisit,
                    v => v.label_originprice.Visible
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Screen,
                    v => v.label_index.Visible
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Screen,
                    v => v.label_del.Visible
                    ).DisposeWith(d);

                this.OneWayBind(ViewModel,
                    vm => vm.Screen,
                    v => v.label_add.Visible
                    ).DisposeWith(d);


                this.label_add.Events().Click.Do(x =>
                {
                    RowValue?.Invoke("+", null);
                })
                .Subscribe()
                .DisposeWith(d);

                this.label_del.Events().Click.Do(x =>
                {
                    RowValue?.Invoke("-", null);
                })
                .Subscribe()
                .DisposeWith(d);

                ViewModel.WhenAnyValue(x => x.Plu.Count)
                .Subscribe(y =>
                {
                    if (y < 0)
                    {
                        Dispose();
                    }
                })
                .DisposeWith(d);

                ViewModel.WhenAnyValue(x => x.Plu.TagList)
                .Subscribe(y =>
                {
                    CreateTag(y);
                })
                .DisposeWith(d);

                ViewModel.WhenAnyValue(x => x.Plu.Tag)
                .Subscribe(y =>
                {
                    ViewModel.ChangeColorCommand.Execute().Subscribe();
                })
                .DisposeWith(d);

            });
        }

        private Color BoolToBorderStyle(bool isClick)
        {
            return isClick ? Color.FromArgb(247, 247, 247) : Color.White;
        }

        private bool BorderStyleToBool(Color color)
        {
            return color == Color.FromArgb(247, 247, 247);
        }

        private void InitEvent()
        {
            this.label_close.Click += (s, e) =>
            {
                this.Dispose();
            };

            this.Disposed += (s, e) =>
            {
                RowDispose?.Invoke(this,e);
            };

            this.Click += (s, e) =>
            {
                RowClick?.Invoke(s, e);
            };

            panel_tag.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            stackPanel_base.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            label_index.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            label_name.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            flowPanel_promote.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            flowPanel_number.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            flowPanel_price.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            label_amount.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            label_count.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            label_price.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };

            label_originprice.Click += (s, e) =>
            {
                RowClick?.Invoke(this, e);
            };
        }
        private string ConvertToPriceUnit(Plu plu)
        {
            return (
                plu.PromotePrice4 > 0 ? plu.PromotePrice4 :
                plu.PromotePrice3 > 0 ? plu.PromotePrice3 :
                plu.PromotePrice2 > 0 ? plu.PromotePrice2 :
                plu.VipPrice > 0 ? Math.Min(plu.VipPrice, plu.Price) :
                plu.PromotePrice1 > 0 ? Math.Min(plu.PromotePrice1, plu.Price) : Math.Min(plu.Price, plu.OriginPrice)
            ).ToString();
        }


        private void CreateTag(List<string> TagList)
        {
            flowPanel_promote.Controls.Clear();
            if (TagList != null && TagList.Count > 0)
            {
                for (int i = 0; i < TagList.Count; i++)
                {
                    AntdUI.Tag tag = new AntdUI.Tag();
                    tag.CloseIcon = false;
                    tag.Text = TagList[i];
                    tag.AutoSize = true;
                    switch (i)
                    {
                        case 0:
                            tag.Type = TTypeMini.Warn;
                            break;
                        case 1:
                            tag.Type = TTypeMini.Success;
                            break;
                        case 2:
                            tag.Type = TTypeMini.Error;
                            break;
                        case 4:
                            tag.Type = TTypeMini.Default;
                            break;
                        case 5:
                            tag.Type = TTypeMini.Warn;
                            break;
                        case 6:
                            tag.Type = TTypeMini.Success;
                            break;
                        case 7:
                            tag.Type = TTypeMini.Primary;
                            break;
                        default:
                            tag.Type = TTypeMini.Primary;
                            break;
                    }
                    flowPanel_promote.Controls.Add(tag);
                }
            }
        }
        string IRow.GetType()
        {
            return "PluRowPro";
        }
    }
}
